package com.hc.likelistenmusic.util;


import com.hc.likelistenmusic.bean.Lrc;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class LrcUtil {
    private static final String CHARSET = "utf-8";
    private static final String ZERO = "0";
    private static final String EMPTY = "";
    private static final String COLON = ":";
    private static final String TEXT_REGEX = "((\\[\\d{2}:\\d{2}\\.\\d{1,6}])+)(.*)";
    private static final String TEXT_REGEX2 = "((\\[\\d{2}:\\d{2}])+)(.*)";
    private static final String TIME_REGEX = "\\[(\\d{2}):(\\d{2})\\.(\\d{1,6})]";
    private static final String TIME_REGEX2 = "\\[(\\d{2}):(\\d{2})]";

    public static List<Lrc> analysisLrcFromFile(File file) {
        try {
            return analysisInner(new FileInputStream(file));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    private static List<Lrc> analysisInner(InputStream inputStream) {
        List<Lrc> lrcList = new ArrayList<>();
        InputStreamReader inputStreamReader = null;
        BufferedReader bufferedReader = null;
        try {
            inputStreamReader = new InputStreamReader(inputStream, CHARSET);
            bufferedReader = new BufferedReader(inputStreamReader);
            String line;
            while ((line = bufferedReader.readLine()) != null) {
                List<Lrc> lineList = analysisLine(line);
                if (lineList != null && !lineList.isEmpty()) {
                    lrcList.addAll(lineList);
                }
            }
            sortLrc(lrcList);
            return lrcList;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (inputStreamReader != null) {
                    inputStreamReader.close();
                }
                if (bufferedReader != null) {
                    bufferedReader.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return lrcList;
    }

    private static void sortLrc(List<Lrc> lrcList) {
        Collections.sort(lrcList, new Comparator<Lrc>() {
            @Override
            public int compare(Lrc o1, Lrc o2) {
                return (int) (o1.getTime() - o2.getTime());
            }
        });
    }

    private static List<Lrc> analysisLine(String line) {
        if (line.trim().isEmpty()) {
            return null;
        }
        List<Lrc> lrcs = new ArrayList<>();
        Matcher matcher = Pattern.compile(TEXT_REGEX).matcher(line);
        if (!matcher.matches()) {
            return analysisLine2(line);
        }
        String time = matcher.group(1);
        String content = matcher.group(3);
        Matcher timeMatcher = Pattern.compile(TIME_REGEX).matcher(time);
        while (timeMatcher.find()) {
            String hour = timeMatcher.group(1);
            String min = timeMatcher.group(2);
            String sec = timeMatcher.group(3);
            Lrc lrc = new Lrc();
            if (content != null && content.length() != 0) {
                int ihour = Integer.parseInt(hour);
                int imin = Integer.parseInt(min);
                int isec;
                if (sec.length() > 2) {
                    String sec3 = sec.substring(2, 3);
                    if (Integer.parseInt(sec3) >= 5) {
                        isec = Integer.parseInt(sec.substring(0, 2)) + 1;
                    } else {
                        isec = Integer.parseInt(sec.substring(0, 2));
                    }
                } else {
                    isec = Integer.parseInt(sec);
                }
                lrc.setTime(ihour * 60 * 1000 + imin * 1000
                        + isec * 10);
                lrc.setText(content);
                lrcs.add(lrc);
            }
        }
        return lrcs;
    }

    private static List<Lrc> analysisLine2(String line) {
        if (line.trim().isEmpty()) {
            return null;
        }
        List<Lrc> lrcs = new ArrayList<>();
        Matcher matcher = Pattern.compile(TEXT_REGEX2).matcher(line);
        if (!matcher.matches()) {
            return null;
        }
        String time = matcher.group(1);
        String content = matcher.group(3);
        Matcher timeMatcher = Pattern.compile(TIME_REGEX2).matcher(time);
        while (timeMatcher.find()) {
            String hour = timeMatcher.group(1);
            String min = timeMatcher.group(2);
            Lrc lrc = new Lrc();
            if (content != null && content.length() != 0) {
                int ihour = Integer.parseInt(hour);
                int imin = Integer.parseInt(min);
                lrc.setTime(ihour * 60 * 1000 + imin * 1000);
                lrc.setText(content);
                lrcs.add(lrc);
            }
        }
        return lrcs;
    }

    public static String formatLrcTime(int lrcTime) {
        int time = lrcTime / 1000;
        if (time < 60) {
            String sec = time < 10 ? ZERO + time : EMPTY + time;
            return ZERO + ZERO + COLON + sec;
        } else if (time <= 3599) {
            int seci = time % 60;
            String sec = seci < 10 ? ZERO + seci : EMPTY + seci;
            int mini = time / 60;
            String min = mini < 10 ? ZERO + mini : EMPTY + mini;
            return min + COLON + sec;
        } else {
            int houri = time / 3600;
            String hour = houri < 10 ? ZERO + houri : EMPTY + houri;
            int minj = time % 3600;
            if (minj < 60) {
                String sec = minj < 10 ? ZERO + minj : EMPTY + minj;
                return hour + COLON + ZERO + ZERO + COLON + sec;
            } else {
                int seci = minj % 60;
                String sec = seci < 10 ? ZERO + seci : EMPTY + seci;
                int mini = minj / 60;
                String min = mini < 10 ? ZERO + mini : EMPTY + mini;
                return hour + COLON + min + COLON + sec;
            }
        }
    }
}
